home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / CallTipWindow.py < prev    next >
Text File  |  2008-10-05  |  6KB  |  172 lines

  1. """A CallTip window class for Tkinter/IDLE.
  2.  
  3. After ToolTip.py, which uses ideas gleaned from PySol
  4. Used by the CallTips IDLE extension.
  5.  
  6. """
  7. from Tkinter import *
  8.  
  9. HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
  10. HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
  11. CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>"
  12. CHECKHIDE_SEQUENCES = ("<KeyRelease>", "<ButtonRelease>")
  13. CHECKHIDE_TIME = 100 # miliseconds
  14.  
  15. MARK_RIGHT = "calltipwindowregion_right"
  16.  
  17. class CallTip:
  18.  
  19.     def __init__(self, widget):
  20.         self.widget = widget
  21.         self.tipwindow = self.label = None
  22.         self.parenline = self.parencol = None
  23.         self.lastline = None
  24.         self.hideid = self.checkhideid = None
  25.  
  26.     def position_window(self):
  27.         """Check if needs to reposition the window, and if so - do it."""
  28.         curline = int(self.widget.index("insert").split('.')[0])
  29.         if curline == self.lastline:
  30.             return
  31.         self.lastline = curline
  32.         self.widget.see("insert")
  33.         if curline == self.parenline:
  34.             box = self.widget.bbox("%d.%d" % (self.parenline,
  35.                                               self.parencol))
  36.         else:
  37.             box = self.widget.bbox("%d.0" % curline)
  38.         if not box:
  39.             box = list(self.widget.bbox("insert"))
  40.             # align to left of window
  41.             box[0] = 0
  42.             box[2] = 0
  43.         x = box[0] + self.widget.winfo_rootx() + 2
  44.         y = box[1] + box[3] + self.widget.winfo_rooty()
  45.         self.tipwindow.wm_geometry("+%d+%d" % (x, y))
  46.  
  47.     def showtip(self, text, parenleft, parenright):
  48.         """Show the calltip, bind events which will close it and reposition it.
  49.         """
  50.         # truncate overly long calltip
  51.         if len(text) >= 79:
  52.             textlines = text.splitlines()
  53.             for i, line in enumerate(textlines):
  54.                 if len(line) > 79:
  55.                     textlines[i] = line[:75] + ' ...'
  56.             text = '\n'.join(textlines)
  57.         self.text = text
  58.         if self.tipwindow or not self.text:
  59.             return
  60.  
  61.         self.widget.mark_set(MARK_RIGHT, parenright)
  62.         self.parenline, self.parencol = map(
  63.             int, self.widget.index(parenleft).split("."))
  64.  
  65.         self.tipwindow = tw = Toplevel(self.widget)
  66.         self.position_window()
  67.         # remove border on calltip window
  68.         tw.wm_overrideredirect(1)
  69.         try:
  70.             # This command is only needed and available on Tk >= 8.4.0 for OSX
  71.             # Without it, call tips intrude on the typing process by grabbing
  72.             # the focus.
  73.             tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
  74.                        "help", "noActivates")
  75.         except TclError:
  76.             pass
  77.         self.label = Label(tw, text=self.text, justify=LEFT,
  78.                            background="#ffffe0", relief=SOLID, borderwidth=1,
  79.                            font = self.widget['font'])
  80.         self.label.pack()
  81.  
  82.         self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME,
  83.                                             self.checkhide_event)
  84.         for seq in CHECKHIDE_SEQUENCES:
  85.             self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
  86.         self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
  87.         self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
  88.                                        self.hide_event)
  89.         for seq in HIDE_SEQUENCES:
  90.             self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
  91.  
  92.     def checkhide_event(self, event=None):
  93.         if not self.tipwindow:
  94.             # If the event was triggered by the same event that unbinded
  95.             # this function, the function will be called nevertheless,
  96.             # so do nothing in this case.
  97.             return
  98.         curline, curcol = map(int, self.widget.index("insert").split('.'))
  99.         if curline < self.parenline or \
  100.            (curline == self.parenline and curcol <= self.parencol) or \
  101.            self.widget.compare("insert", ">", MARK_RIGHT):
  102.             self.hidetip()
  103.         else:
  104.             self.position_window()
  105.             self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
  106.  
  107.     def hide_event(self, event):
  108.         if not self.tipwindow:
  109.             # See the explanation in checkhide_event.
  110.             return
  111.         self.hidetip()
  112.  
  113.     def hidetip(self):
  114.         if not self.tipwindow:
  115.             return
  116.  
  117.         for seq in CHECKHIDE_SEQUENCES:
  118.             self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
  119.         self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid)
  120.         self.checkhideid = None
  121.         for seq in HIDE_SEQUENCES:
  122.             self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
  123.         self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
  124.         self.hideid = None
  125.  
  126.         self.label.destroy()
  127.         self.label = None
  128.         self.tipwindow.destroy()
  129.         self.tipwindow = None
  130.  
  131.         self.widget.mark_unset(MARK_RIGHT)
  132.         self.parenline = self.parencol = self.lastline = None
  133.  
  134.     def is_active(self):
  135.         return bool(self.tipwindow)
  136.  
  137.  
  138.  
  139. ###############################
  140. #
  141. # Test Code
  142. #
  143. class container: # Conceptually an editor_window
  144.     def __init__(self):
  145.         root = Tk()
  146.         text = self.text = Text(root)
  147.         text.pack(side=LEFT, fill=BOTH, expand=1)
  148.         text.insert("insert", "string.split")
  149.         root.update()
  150.         self.calltip = CallTip(text)
  151.  
  152.         text.event_add("<<calltip-show>>", "(")
  153.         text.event_add("<<calltip-hide>>", ")")
  154.         text.bind("<<calltip-show>>", self.calltip_show)
  155.         text.bind("<<calltip-hide>>", self.calltip_hide)
  156.  
  157.         text.focus_set()
  158.         root.mainloop()
  159.  
  160.     def calltip_show(self, event):
  161.         self.calltip.showtip("Hello world")
  162.  
  163.     def calltip_hide(self, event):
  164.         self.calltip.hidetip()
  165.  
  166. def main():
  167.     # Test code
  168.     c=container()
  169.  
  170. if __name__=='__main__':
  171.     main()
  172.